<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>高德地图实现画点、线、面及编辑功能</title>
    <script type="text/javascript">
      window._AMapSecurityConfig = {
        securityJsCode: "a56a53e0e1f5948c029c0c5d36a5eb81",
      };
    </script>
    <script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=2.0&key=3d7b84db867720a4a814dacd4c0676bf&plugin=AMap.ToolBar,AMap.MouseTool,AMap.PolyEditor,AMap.Polyline,AMap.Polygon,AMap.Driving"
    ></script>
    <style>
      #map {
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
      }
      .line-btn {
        width: 100px;
        height: 100%;
        position: fixed;
        top: 0;
        left: 10px;
        z-index: 8;
      }
      .operate,
      .btn {
        width: 100px;
        height: 40px;
        background: #447bf3;
        color: #fff;
        float: left;
        display: block;
        line-height: 40px;
        margin: 10px 0;
        text-align: center;
        border-radius: 100px;
        cursor: pointer;
      }
      .btn {
        background: #f36d44;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <div class="line-btn">
      <div class="operate" onclick="openMarkerTool()">点</div>
      <div class="operate" onclick="openPolylineTool()">线</div>
      <div class="operate" onclick="openPolygonTool()">面</div>
      <div class="btn" onclick="editClick()">编辑</div>
      <div class="btn" onclick="saveClick()">保存</div>
      <div class="btn" onclick="clearClick()">清除</div>
    </div>
    <script>
      var map,
        zoom = 10,
        handler;
      let isEdit = false; // 是否启用编辑
      let pointOriginalArr = [[120.2536, 30.27093]]; // 点原始数组
      let lineOriginalArr = [
        [
          [119.86084, 30.41702],
          [119.96796, 30.47353],
          [119.98718, 30.36758],
        ],
        [
          [119.91714, 30.1855],
          [120.10666, 30.27923],
        ],
      ]; // 线原始数组
      let polygonOriginalArr = [
        [
          [119.5752, 30.35392],
          [119.72488, 30.35273],
          [119.65347, 30.26025],
        ],
        [
          [120.49118, 30.29109],
          [120.70541, 30.30532],
          [120.50629, 30.20211],
          [120.69855, 30.22703],
        ],
      ]; // 面原始数组

      // 初始化地图对象
      map = new AMap.Map("map", {
        zoom: zoom,
        center: [120.216329, 30.252589],
      });

      // 如果一进来地图就需要回显
      showPoint();
      showPolyLine();
      showPolygon();

      function showPoint() {
        let pointArr = [];
        pointOriginalArr.forEach((item, index) => {
          let arr = [];
          arr.push(new AMap.LngLat(item[0], item[1]));
          pointArr.push(arr);
        });
        console.log("pointArr", pointArr);

        pointArr.forEach((item, index) => {
          var marker = new AMap.Marker({
            position: item[0],
            icon: "https://vdata.amap.com/icons/b18/1/2.png", //添加 icon 图标 URL

            // icon: new AMap.Icon({
            //   image: "../images/point.png",
            //   size: new AMap.Size(24, 28),
            // }),
          });
          map.add(marker);
          if (!isEdit) return;
          marker.setDraggable(true);
          AMap.Event.addListener(marker, "dragend", function (e) {
            updatePointOriginalList([e.lnglat.lng, e.lnglat.lat], index);
          });
        });
      }

      // 更新点位数据，用于最后保存
      function updatePointOriginalList(arr, index) {
        pointOriginalArr[index] = arr;
      }

      function showPolyLine() {
        let lineArr = [];
        lineOriginalArr.forEach((item, index) => {
          let arr = [];
          item.forEach((item1) => {
            arr.push(new AMap.LngLat(item1[0], item1[1]));
          });
          lineArr.push(arr);
        });
        lineArr.forEach((item, index) => {
          var line = new AMap.Polyline({
            path: item,
            strokeColor: "#ff0000",
            strokeWeight: 5,
          });
          map.add(line);
          if (!isEdit) return;
          line.editor = new AMap.PolyEditor(map, line);
          line.editor.open();

          // // 监听 addnode 事件
          // line.editor.on("addnode", function (e) {
          //   console.log(111);
          //   // const path = line.getPath();
          //   // let arr = path.map((item) => [item.lng, item.lat]);
          //   // updateLineOriginalList(arr, index);
          // });

          // // 监听 removenode 事件
          // line.editor.on("removenode", function (e) {
          //   console.log(222);
          //   // const path = line.getPath();
          //   // let arr = path.map((item) => [item.lng, item.lat]);
          //   // updateLineOriginalList(arr, index);
          // });

          line.editor.on("addnode", function (e) {
            console.log(111);

            const path = line.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            updateLineOriginalList(arr, index);
          });
          line.editor.on("removenode", function (e) {
            console.log(222);
            const path = line.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            updateLineOriginalList(arr, index);
          });
        });
      }

      // 更新线的数据，用于最后保存
      function updateLineOriginalList(arr, index) {
        console.log(3333);

        lineOriginalArr[index] = arr;
      }

      function showPolygon() {
        let polygonArr = [];
        polygonOriginalArr.forEach((item, index) => {
          let arr = [];
          item.forEach((item1) => {
            arr.push(new AMap.LngLat(item1[0], item1[1]));
          });
          polygonArr.push(arr);
        });
        polygonArr.forEach((item, index) => {
          var polygon = new AMap.Polygon({
            path: item,
            strokeColor: "#ff0000",
            strokeWeight: 5,
            fillColor: "#ff0000",
            fillOpacity: 0.3,
          });
          map.add(polygon);
          if (!isEdit) return;
          polygon.editor = new AMap.PolyEditor(map, polygon);
          polygon.editor.open();
          AMap.Event.addListener(polygon.editor, "addnode", function (e) {
            console.log(111);
            const path = polygon.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            updatePolygonOriginalList(arr, index);
          });
          AMap.Event.addListener(polygon.editor, "removenode", function (e) {
            const path = polygon.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            updatePolygonOriginalList(arr, index);
          });
        });
      }

      // 更新面的数据，用于最后保存
      function updatePolygonOriginalList(arr, index) {
        console.log(2222);

        polygonOriginalArr[index] = arr;
      }

      // 打点
      function openMarkerTool() {
        map.clearEvents("click");
        handler = AMap.Event.addListener(map, "click", function (e) {
          pointOriginalArr.push([e.lnglat.lng, e.lnglat.lat]);
          showPoint();
        });
      }

      // 画线
      function openPolylineTool() {
        map.clearEvents("click");
        handler = new AMap.MouseTool(map);
        handler.polyline({
          strokeColor: "#ff0000",
          strokeWeight: 3,
        });
        handler.on("add", function (e) {
          if (e.type === "polyline") {
            const path = e.obj.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            lineOriginalArr.push(arr);
            showPolyLine();
          }
        });
      }

      // 画多边形
      function openPolygonTool() {
        map.clearEvents("click");
        handler = new AMap.MouseTool(map);
        handler.polygon({
          strokeColor: "#ff0000",
          strokeWeight: 3,
        });
        handler.on("add", function (e) {
          if (e.type === "polygon") {
            const path = e.obj.getPath();
            let arr = [];
            path.forEach((item, index) => {
              arr.push([item.lng, item.lat]);
            });
            polygonOriginalArr.push(arr);
            showPolygon();
          }
        });
      }

      // 编辑
      function editClick() {
        isEdit = true;
        map.clearMap();
        showPoint();
        showPolyLine();
        showPolygon();
      }

      // 保存
      function saveClick() {
        isEdit = false;
        map.clearMap();
        showPoint();
        showPolyLine();
        showPolygon();
        console.log(
          "saveClick========",
          pointOriginalArr,
          lineOriginalArr,
          polygonOriginalArr
        );
      }

      // 清除
      function clearClick() {
        isEdit = false;
        map.clearMap();
        pointOriginalArr = [];
        lineOriginalArr = [];
        polygonOriginalArr = [];
      }
    </script>
  </body>
</html>
